   package cn.edu.nju.ws.sview.views.data;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.PriorityQueue;
import java.util.Map.Entry;

import cn.edu.nju.ws.sview.database.DBConnectionFactory;

public class RecommCache{
	private HashMap<String, Integer> items;
	private Date lastUpdateTime;
	/**
	 * 传入此次浏览的时间
	 * @param time String表示，必须为"YY-MM-DD hh:mm:ss"格式
	 */
	public RecommCache(Date time){
		this.lastUpdateTime = time;
		items = new HashMap<String, Integer>();
	}
	
	/**
	 * 如果当前的items里面没有这个item，则将这个item加入到items里面，对应键值为1；否则，更新对应键值对的值，自增1
	 * @param itemId 要填入item的id
	 * @param itemType 要填入item的type
	 * @param time 这次更新的访问时间
	 */
	public void union(RecommItem temp, Date t){
		//RecommItem temp = new RecommItem(itemId, itemType);
		if(items.containsKey(temp.toString())){
			items.put(temp.toString(), items.get(temp.toString()) + 1);
		}
		else{
			items.put(temp.toString(), 1);
		}
		this.lastUpdateTime = t;
	}
	public void union(RecommItem temp, Date t, int times){
		//RecommItem temp = new RecommItem(itemId, itemType);
		if(items.containsKey(temp.toString())){
			items.put(temp.toString(), items.get(temp.toString()) + times);
		}
		else{
			items.put(temp.toString(), times);
		}
		this.lastUpdateTime = t;
	}
	
	/**
	 * 获得对应item的keyValue
	 * @param itemId
	 * @param itemType
	 * @return
	 */

	public int size(){
		return items.size();
	}
	private RecommItem string2Item(String s){
		String[] ss = s.split("-");
		int id = Integer.valueOf(ss[0]);
		String ty = ss[1];
		return new RecommItem(id, Integer.valueOf(ty));
	}
	
	public int getKeyValue(RecommItem item){
		return items.get(item.toString());
	}
	
	public Date lastUpdateTime(){
		return (Date) lastUpdateTime.clone();
	}
	
	/**
	 * 将HashMap中的所有key按其对应的value非递增顺序加入到优先级队列中
	 * @return 返回这个优先级队列
	 */
	public PriorityQueue<RecommItem> getPriorityQueue(){
		PriorityQueue<RecommItem> pq = new PriorityQueue<RecommItem>(items.size() > 0 ? items.size() : 1, 
				new Comparator<RecommItem>(){

			@Override
			public int compare(RecommItem arg0, RecommItem arg1) {
				int a = items.get(arg0.toString()), b = items.get(arg1.toString());
				if(a > b)
					return -1;
				if(a < b)
					return 1;
				return 0;
			}
			public boolean equals(Object obj){
				return false;
			}
		});
		Iterator<String> iter = items.keySet().iterator();	
		while(iter.hasNext()){
			pq.add(string2Item(iter.next()));
		}
		return pq;
	}
	public String toString(){
		String ret = "";
		Iterator<Entry<String, Integer>> iter = items.entrySet().iterator();
		while(iter.hasNext()){
			Entry<String, Integer> e = iter.next();
			ret += "<" + e.getKey() + ", " + e.getValue() + "> ";
		}
		return ret;
	}
	
	/**
	 * 后来的使用rec_relation保存中间结果的方案后添加了这个方法，从rec_relation中提取出中间结果，返回对应的RecommCache
	 * @param itemId
	 * @param itemType
	 * @param now 访问时间
	 * @return 当天之前的中间结果
	 * @throws SQLException
	 */
	public static RecommCache getInstance(int itemId, int itemType, Date now) throws SQLException{
		RecommCache instance = new RecommCache(now);
		
		// 从DB的rec_relation表中取出存储的中间结果
		Connection conn = DBConnectionFactory.getConnection();
		try{
			PreparedStatement ps = conn.prepareStatement(
				"SELECT rec_id, rec_type, day_related_times FROM rec_relation WHERE item_id = ? " +
				"AND item_type = ?");
			ps.setInt(1, itemId);
			ps.setString(2, "" + itemType);
			ResultSet rs = ps.executeQuery();
			while(rs.next()){
				int recId = rs.getInt("rec_id");
				String recType = rs.getString("rec_type");
				int times = rs.getInt("day_related_times");
				instance.union(new RecommItem(recId, Integer.valueOf(recType)), now, times);
			}
			ps.close();
			rs.close();
		}finally{
			conn.close();
		}
		return instance;
	}
}